package com.personal.dataconvert.bean;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.w3c.dom.Element;

import com.personal.core.bean.CountEntity;
import com.personal.core.port.HaveDeepAndChildren;
import com.personal.core.utils.CoreUtil;
import com.personal.core.utils.DeepChildrenUtil;

/**
 * 头部配置，Excel，Html公用实体
 * 对于需要展示和拼接多表头均可以继承该配置
 * @author cuibo
 *
 */
public class HeaderConfig implements HaveDeepAndChildren, Serializable
{
    /** 不是一个HeaderConfig */
    public static final HeaderConfig NAH = new HeaderConfig();;
    
    public static final String ZZ = "自增";

    public static final String CENTER = "center";

    public static final String LEFT = "left";

    public static final String RIGHT = "right";
    

    public static final String STRING = "string";
    public static final String DATE = "date";
    public static final String NUMBER = "number";

    /**
     *
     */
    private static final long serialVersionUID = -5381010874773120193L;

    /** 所属Sheet页的配置 */
    private SheetConfig sheetConfig;
    
    /** 父节点 */
    private HeaderConfig parent;
    
    /** 子节点集合 */
    private List<HeaderConfig> children;
    
    /** 节点深度 */
    private int deepLength;
    
    /** 名称 */
    private String displayName;

    /** 值对应的属性 */
    private String value;
    
    /** 数据类型(防止底层将如2.10 这种文本转成数字，导致末尾的0丢失) */
    private String dataType;
    
    /** 是否展示 */
    private boolean display = true;
    
    /** 生成Excel的所在列 */
    private int colIndex;

    /** 生成Excel的跨列 */
    private int colspan;

    /** 生成Excel的所在行 */
    private int rowIndex;

    /** 生成Excel的跨行 */
    private int rowspan;
    
    /** 唯一标识（使用路径当做唯一标识）,即 xxxx 表头分隔符 xxxx 的格式 */
    private String path;

    /** 样式 */
    private String align;

    /** 列宽 */
    private int width = -1;
    
    /** 格式化信息 */
    private String formatInfo;
    
    /** 表头样式信息 */
    private String styleClass;
    
    /** 是否是多表头的根节点（支持表头中包含如：A,B,B.D,B.E的形式 ） */
    private boolean overHeaderRoot = false;
    
    public HeaderConfig()
    {
    }

    /**
     * 子节点构造
     * @param displayName
     * @param deepLength
     * @param parent
     * @param path
     * @param align
     * @param width
     */
    public HeaderConfig(String displayName, int deepLength, HeaderConfig parent, String path, String align, int width)
    {
        super();
        this.displayName = displayName;
        this.deepLength = deepLength;
        this.parent = parent;
        this.path = path;
        this.align = align;
        this.width = width;
    }
    
    /**
     * 子节点构造
     * @param displayName
     * @param value
     * @param deepLength
     * @param parent
     * @param path
     * @param align
     * @param width
     */
    public HeaderConfig(String displayName, String value, int deepLength, HeaderConfig parent, String path,
            String align, int width)
    {
        super();
        this.displayName = displayName;
        this.value = value;
        this.deepLength = deepLength;
        this.parent = parent;
        this.path = path;
        this.align = align;
        this.width = width;
    }
    
    /**
     * 父节点构造
     * @param displayName
     * @param value
     * @param deepLength
     * @param path
     * @param align
     * @param width
     */
    public HeaderConfig(String displayName, String value, int deepLength, String path, String align, int width)
    {
        super();
        this.displayName = displayName;
        this.value = value;
        this.path = path;
        this.deepLength = deepLength;
        this.align = align;
        this.width = width;
    }

    /**
     * 添加子集信息
     */
    public void addChilds(HeaderConfig child)
    {
        getChildren().add(child);
    }

    @Override
    public List<HeaderConfig> getChildren()
    {
        if (children == null)
        {
            children = new ArrayList<HeaderConfig>();
        }
        return children;
    }

    public void setChildren(List<HeaderConfig> children)
    {
        this.children = children;
    }

    public int getColIndex()
    {
        return colIndex;
    }

    public int getColspan()
    {
        return colspan;
    }

    public String getDataType()
    {
        return dataType;
    }

    @Override
    public int getDeepLength()
    {
        return deepLength;
    }

    public String getDisplayName()
    {
        return displayName;
    }

    /**
     * 获取该节点所有叶子节点
     * @return
     */
    public List<? extends HeaderConfig> getLeafHeader()
    {
        if (getChildren() == null || getChildren().isEmpty())
        {
            return null;
        }
        List<HeaderConfig> result = new ArrayList<HeaderConfig>();
        for (HeaderConfig headerConfig : getChildren())
        {
            getLeafHeader(headerConfig, result);
        }
        return result;
    }
    
    /**
     * 获取该节点所有叶子节点(没有叶子节点则返回本身)
     * @return
     */
    public List<HeaderConfig> getLeafHeaderWithThis()
    {
        List<HeaderConfig> result = new ArrayList<HeaderConfig>();
        if (getChildren() == null || getChildren().isEmpty())
        {
            result.add(this);
            return result;
        }
        for (HeaderConfig headerConfig : getChildren())
        {
            getLeafHeader(headerConfig, result);
        }
        return result;
    }

    /**
     * 获取当前节点距离和最大深度节点的深度差
     * @return
     */
    public int getMaxDeepLength()
    {
        if (getChildren().size() > 0)
        {
            return DeepChildrenUtil.getMaxDeep(getChildren()) - getDeepLength();
        } else
        {
            return 0;
        }
    }

    /**
     * 获取当前节点的最大宽度作为跨列数(不跨列则返回1)
     * @param countEntity 计数器
     * @return
     */
    public int getMaxWidth(CountEntity countEntity)
    {
        if (getChildren().size() > 0)
        {
            for (HeaderConfig cellNode : getChildren())
            {
                // 2016 10 28 提供是否显示选择
                if (!cellNode.isDisplay())
                {
                    continue;
                }
                cellNode.getMaxWidth(countEntity);
            }
        } else
        {
            // 加1
            countEntity.add();
        }
        return countEntity.getCount() == 0 ? 1 : countEntity.getCount();
    }

    /**
     * 获取当前节点的最大宽度作为跨列数(不跨列则返回1)
     *（如果隐藏列集合中包括其子节点，那么其跨列数不能加1）
     * @param countEntity 计数器
     * @param hidelColumns 隐藏列
     * @return
     */
    public int getMaxWidth(CountEntity countEntity, Set<String> hidelColumns)
    {
        if (getChildren().size() > 0)
        {
            for (HeaderConfig cellNode : getChildren())
            {
                // 2016 10 28 提供是否显示选择
                if (!cellNode.isDisplay())
                {
                    continue;
                }
                if (hidelColumns != null && !hidelColumns.isEmpty() && hidelColumns.contains(cellNode.getPath()))
                {
                    continue;
                }
                cellNode.getMaxWidth(countEntity);
            }
        } else
        {
            // 加1
            countEntity.add();
        }
        return countEntity.getCount() == 0 ? 1 : countEntity.getCount();
    }
    
    @Override
    public HeaderConfig getParent()
    {
        return parent;
    }

    public void setParent(HeaderConfig parent)
    {
        this.parent = parent;
    }

    public String getPath()
    {
        return path;
    }

    public int getRowIndex()
    {
        return rowIndex;
    }

    public int getRowspan()
    {
        return rowspan;
    }

    public SheetConfig getSheetConfig() throws Exception
    {
        if (sheetConfig == null)
        {
            throw new Exception("存在下载表头配置对应的Sheet页配置信息为空，请设置表头配置的Sheet页配置！");
        }
        return sheetConfig;
    }

    public String getValue()
    {
        return value;
    }

    public int getWidth()
    {
        return width;
    }

    public boolean isDisplay()
    {
        return display;
    }

    /**
     * 是否是叶子阶段
     */
    public boolean isLeaf()
    {
        return children == null || children.isEmpty();
    }

    public void setColIndex(int colIndex)
    {
        this.colIndex = colIndex;
    }

    public void setColspan(int colspan)
    {
        this.colspan = colspan;
    }

    public void setDataType(String dataType)
    {
        this.dataType = dataType;
    }

    @Override
    public void setDeepLength(int deepLength)
    {
        this.deepLength = deepLength;
    }

    public void setDisplay(boolean display)
    {
        this.display = display;
    }

    public void setDisplayName(String displayName)
    {
        this.displayName = displayName;
    }

    public void setPath(String path)
    {
        this.path = path;
    }

    public void setRowIndex(int rowIndex)
    {
        this.rowIndex = rowIndex;
    }

    public void setRowspan(int rowspan)
    {
        this.rowspan = rowspan;
    }

    public void setSheetConfig(SheetConfig sheetConfig)
    {
        this.sheetConfig = sheetConfig;
    }

    public String getAlign()
    {
        return align;
    }

    public void setAlign(String align)
    {
        this.align = align;
    }

    public void setValue(String value)
    {
        this.value = value;
    }

    public void setWidth(int width)
    {
        this.width = width;
    }
    
    public String getFormatInfo()
    {
        return formatInfo;
    }

    public void setFormatInfo(String formatInfo)
    {
        this.formatInfo = formatInfo;
    }
    
    public boolean isOverHeaderRoot()
    {
        return overHeaderRoot;
    }

    public void setOverHeaderRoot(boolean overHeaderRoot)
    {
        this.overHeaderRoot = overHeaderRoot;
    }

    public String getStyleClass()
    {
        return styleClass;
    }

    public void setStyleClass(String styleClass)
    {
        this.styleClass = styleClass;
    }

    private void getLeafHeader(HeaderConfig headerConfig, List<HeaderConfig> result)
    {
        if (headerConfig.getChildren() == null || headerConfig.getChildren().isEmpty())
        {
            result.add(headerConfig);
        } else
        {
            for (HeaderConfig config : headerConfig.getChildren())
            {
                getLeafHeader(config, result);
            }
        }
    }

    /**
     * 由Xml节点填充信息
     * @param headerElement
     */
    public void fillInfo(Element headerElement)
    {
        if (headerElement == null)
        {
            return;
        }
        this.setAlign(headerElement.getAttribute("align"));
        this.setDisplayName(headerElement.getAttribute("displayName"));
        this.setValue(headerElement.getAttribute("value"));
        if (!CoreUtil.isEmpty(headerElement.getAttribute("width")))
        {
            this.setWidth(CoreUtil.parseInt(headerElement.getAttribute("width")));
        }
        this.setDataType(headerElement.getAttribute("dataType"));
        this.setFormatInfo(headerElement.getAttribute("formatInfo"));
        this.setDisplay(!"false".equals(headerElement.getAttribute("display")));
    }

    public List<String> getColumLabel()
    {
        List<HeaderConfig> headerConfigs = getLeafHeaderWithThis();
        if (headerConfigs == null || headerConfigs.isEmpty())
        {
            return null;
        }
        List<String> result = new ArrayList<String>();
        for (HeaderConfig headerConfig : headerConfigs)
        {
            result.add(headerConfig.getPath());
        }
        return result;
    }

}
